package org.example.Listener;

import com.google.gson.Gson;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import org.example.Response.SpeechAssessmentResponse;
import org.example.Domain.ParamBuilder;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Base64;

@Data
@Slf4j
public class SpeechAssessmentListener extends WebSocketListener {

    private MultipartFile file;
    private String params;
    private StringBuilder answer;

    public static Gson gson = new Gson();
    final Base64.Encoder encoder = Base64.getEncoder();//编码
    final Base64.Decoder decoder = Base64.getDecoder();//解码

    public static final int StatusFirstFrame = 0;//第一帧
    public static final int StatusContinueFrame = 1;//中间帧
    public static final int StatusLastFrame = 2;//最后一帧

    /**
     * websocket连接关闭标志
     */
    private Boolean wsCloseFlag = false;

    public SpeechAssessmentListener(MultipartFile file,String params,StringBuilder answer) {
        this.file = file;
        this.params = params;
        this.answer = answer;
    }

    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        super.onOpen(webSocket, response);
        new Thread(() -> {
            //连接成功，开始发送数据
            int frameSize = 1280; //每一帧音频的大小,建议每 40ms 发送 1280B，大小可调整，但是不要超过19200B，即base64压缩后能超过26000B，否则会报错10163数据过长错误
            int intervel = 40;
            int status = 0;  // 音频的状态
            //FileInputStream fs = new FileInputStream("0.pcm");
            webSocket.send(params);
            //ttp(webSocket);
            try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(file.getBytes()))  {
                System.out.println("读入了音频文件=>" + file.getName() + "/大小=>" + file.getSize());
                byte[] buffer = new byte[frameSize];
                // 发送音频
                end:
                while (true) {
                    int len = byteArrayInputStream.read(buffer);
                    System.out.println("读入长度=>" + len);
                    if (len == -1) {
                        status = StatusLastFrame;  //文件读完，改变status 为 2
                    }

                    switch (status) {
                        case StatusFirstFrame:   // 第一帧音频status = 0
                            send(webSocket,1,1, Base64.getEncoder().encodeToString(Arrays.copyOf(buffer, len)));
                            status=StatusContinueFrame;//中间帧数
                            break;

                        case StatusContinueFrame:  //中间帧status = 1
                            send(webSocket,2,1,Base64.getEncoder().encodeToString(Arrays.copyOf(buffer, len)));
                            break;

                        case StatusLastFrame:    // 最后一帧音频status = 2 ，标志音频发送结束
                            send(webSocket,4,2,"");
                            System.out.println("sendlast");
                            break end;
                    }
                    Thread.sleep(intervel); //模拟音频采样延时
                }
                System.out.println("all data is send");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

    //客户端接收服务端消息
    @Override
    public void onMessage(WebSocket webSocket, String text) {
        super.onMessage(webSocket, text);
        //System.out.println(text);
        SpeechAssessmentResponse resp = gson.fromJson(text, SpeechAssessmentResponse.class);
        if (resp != null) {
            if (resp.getCode() != 0) {
                System.out.println( "code=>" + resp.getCode() + " error=>" + resp.getMessage() + " sid=" + resp.getSid());
                System.out.println( "错误码查询链接：https://www.xfyun.cn/document/error-code");
                return;
            }
            if (resp.getData() != null) {
                // base64解码器
                //中间结果处理
                if (resp.getData().getStatus() == 2) {
                    try {
                        String answerXML = new String(decoder.decode(resp.getData().getData()), "UTF-8");
                        answer.append(answerXML);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    wsCloseFlag = true;
                    webSocket.close(1000, "");
                }
            }
        }
        //System.out.println("response==>"+text);
    }

    //客户端给服务端发送数据
    public void send(WebSocket webSocket, int aus,int status, String data) {
        ParamBuilder p = new ParamBuilder();
        p.add("business", new ParamBuilder()
                .add("cmd", "auw")
                .add("aus", aus)
                .add("aue", "lame")
        ).add("data",new ParamBuilder()
                .add("status",status)
                .add("data",data)
                .add("data_type",1)
                .add("encoding","raw")
        );
        //System.out.println("发送的数据"+p.toString());
        webSocket.send(p.toString());
    }

}
